package hn.sigit.model.ladm.spatialunit;

import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.type.Type;
import org.hibernate.usertype.CompositeUserType;

public class LA_VolumeValueUserType implements CompositeUserType {
	private Type stringEnumUserType;
	
	public LA_VolumeValueUserType() {
		stringEnumUserType = Hibernate.custom(hn.sigit.model.usertypes.StringEnumUserType.class,
				new String[] {"enumClassName"},
				new String[] {"hn.sigit.model.ladm.spatialunit.LA_VolumeType"});
	}
	
	@Override
	public String[] getPropertyNames() {
		return new String[] {"volumeType", "volumeSize"};
	}

	@Override
	public Type[] getPropertyTypes() {
		return new Type[] {stringEnumUserType, Hibernate.BIG_DECIMAL};
	}

	@Override
	public Object getPropertyValue(Object component, int property)
			throws HibernateException {
		LA_VolumeValue volumeValue = (LA_VolumeValue)component;
		if (property == 0)
			return volumeValue.getVolumeType();
		else
			return volumeValue.getVolumeSize();
	}

	@Override
	public void setPropertyValue(Object component, int property, Object value)
			throws HibernateException {
		throw new UnsupportedOperationException();
	}

	@Override
	public Class returnedClass() {
		return LA_VolumeValue.class;
	}

	@Override
	public boolean equals(Object x, Object y) throws HibernateException {
		if (x == y) return true;
		if (x == null || y == null) return false;
		return x.equals(y);
	}

	@Override
	public int hashCode(Object x) throws HibernateException {
		return x.hashCode();
	}

	@Override
	public Object nullSafeGet(ResultSet rs, String[] names,
			SessionImplementor session, Object owner)
			throws HibernateException, SQLException {

		LA_VolumeType volumeType = LA_VolumeType.valueOf(rs.getString(names[0]));
		if (rs.wasNull()) return null;
		
		BigDecimal volumeSize = rs.getBigDecimal(names[1]);
		if (rs.wasNull()) return null;
		
		return new LA_VolumeValue(volumeType, volumeSize);
	}

	@Override
	public void nullSafeSet(PreparedStatement st, Object value, int index,
			SessionImplementor session) throws HibernateException, SQLException {
		
		if (value == null) {
			int sqlType = stringEnumUserType.sqlTypes(null)[0];
			
			st.setNull(index, sqlType);
			st.setNull(index+1, Hibernate.BIG_DECIMAL.sqlType());
		}
		else {
			LA_VolumeValue volumeValue = (LA_VolumeValue)value;
			
			st.setString(index, volumeValue.getVolumeType().toString());
			st.setBigDecimal(index+1, volumeValue.getVolumeSize());
		}
	}

	@Override
	public Object deepCopy(Object value) throws HibernateException {
		return value;
	}

	@Override
	public boolean isMutable() {
		return false;
	}

	@Override
	public Serializable disassemble(Object value, SessionImplementor session)
			throws HibernateException {
		return (Serializable)value;
	}

	@Override
	public Object assemble(Serializable cached, SessionImplementor session,
			Object owner) throws HibernateException {
		return cached;
	}

	@Override
	public Object replace(Object original, Object target,
			SessionImplementor session, Object owner) throws HibernateException {
		return original;
	}

}
